home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / etc / swapBuffer.c < prev    next >
C/C++ Source or Header  |  1989-07-21  |  27KB  |  926 lines

  1. /*
  2.  * swapBuffer.c --
  3.  *
  4.  *    Byte-swapping routines.  Note that this may be clumsy and slow
  5.  *    at first since data is copied twice in some instances.
  6.  *
  7.  *    Current bad assumption: I don't check whether I'm running off the
  8.  *    end of a buffer during a particular copy (a byte copy, a half-word
  9.  *    copy, word copy).  Fix this by checking right before the copy?.
  10.  *
  11.  *
  12.  * Copyright 1988 Regents of the University of California
  13.  * Permission to use, copy, modify, and distribute this
  14.  * software and its documentation for any purpose and without
  15.  * fee is hereby granted, provided that the above copyright
  16.  * notice appear in all copies.  The University of California
  17.  * makes no representations about the suitability of this
  18.  * software for any purpose.  It is provided "as is" without
  19.  * express or implied warranty.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/swapBuffer.c,v 1.9 89/07/01 02:35:23 rab Exp $ SPRITE (Berkeley)";
  24. #endif not lint
  25.  
  26.  
  27. #include "sprite.h"
  28. #include "ctype.h"
  29. #include "string.h"
  30. #include "swapBuffer.h"
  31.  
  32. /*
  33.  * On nasty errors we want to panic in a user process, but not let a
  34.  * user process panic in the kernel.
  35.  */
  36. #ifdef KERNEL
  37. #include "user/sys.h"
  38. #define FakePanicVoid(errstring)    \
  39.     Sys_Panic(SYS_WARNING, errstring);    \
  40.     return;
  41. #define    FakePanicValue(errstring)    \
  42.     Sys_Panic(SYS_WARNING, errstring);    \
  43.     return 0;
  44. #else /* KERNEL */
  45. #define FakePanicVoid(errstring)    \
  46.     panic(errstring);
  47. #define FakePanicValue(errstring)    \
  48.     panic(errstring);
  49. #endif /* KERNEL */
  50.  
  51. extern    long    strtol();
  52. extern    void    panic();
  53.  
  54. /*
  55.  * Forward declarations of procedures defined in this file.
  56.  */
  57. static  int     GetByte();
  58. static  int     GetHalfWord();
  59. static  int     GetWord();
  60. static  int     GetDoubleWord();
  61. static  void    CalcPutByteSize();
  62. static  void    CalcPutHalfWordSize();
  63. static  void    CalcPutWordSize();
  64. static  void    CalcPutDoubleSize();
  65. static  int     PutByte();
  66. static  int     PutHalfWord();
  67. static  int     PutWord();
  68. static  int     PutDoubleWord();
  69. static  int    CalcSize();
  70. static  int     CopyData();
  71.  
  72.  
  73.  
  74. /*
  75.  *----------------------------------------------------------------------
  76.  *
  77.  * Swap_Buffer -- 
  78.  *
  79.  *    Byte-swap incoming buffers from inType byte-order and alignment
  80.  *    to outType byte-order and alignment.
  81.  *
  82.  * Results:
  83.  *    None.
  84.  *
  85.  * Side effects:
  86.  *    The data is copied from the inBuf to the outBuf,
  87.  *    with byte-swapping or padding done as necessary.  *outSizePtr comes
  88.  *    in with the size in bytes of the outBuf passed in.  As we return,
  89.  *    *outSizePtr contains the actual size of swapped data.  If the number
  90.  *    is larger than when it came in, then there wasn't enough space in
  91.  *    outBuf, but we return how much space there should have been to
  92.  *    swap the data correctly, so the calling routine could reallocate
  93.  *    a larger buffer.   If *outSizePtr returns as 0, then something
  94.  *    else went wrong, such as the format string contained garbage or
  95.  *    contained a '*' that was not the last character, or the inBuf was
  96.  *    too short for the format string, or some such other error.  A
  97.  *    panic() in a user process or a Sys_Panic(SYS_WARNING, xxx) in the
  98.  *    kernel will describe the error.
  99.  *
  100.  *----------------------------------------------------------------------
  101.  */
  102. void
  103. Swap_Buffer(inBuf, inSize, inType, outType, format, outBuf, outSizePtr)
  104.     char    *inBuf;        /* in-coming buffer with data to swap */
  105.     int        inSize;        /* in BYTES - size of in-coming data */
  106.     int        inType;        /* byte-order/padding of in-coming buffer */
  107.     int        outType;    /* byte-order/padding of out-going buffer */
  108.     char    *format;    /* format string of in-coming data */
  109.     char    *outBuf;    /* where to put byte-swapped data */
  110.     int        *outSizePtr;    /* in-out param: size of outBuf passed in,
  111.                  * we calculate actual size of swapped data,
  112.                  * in BYTES and return that.  See procedure
  113.                  * comment for more details.
  114.                  */
  115. {
  116.     char    *inPtr;
  117.     char    *outPtr;
  118.     char    *formatPtr;
  119.     char    byteBuf[1];
  120.     char    halfWordBuf[2];
  121.     char    wordBuf[4];
  122.     char    doubleBuf[8];
  123.     int        outSize;
  124.     int        okayP = 1;
  125.     char    *cPtr;
  126.  
  127.  
  128. #ifdef NOTDEF
  129.     if (((unsigned int) inBuf) % 4  != 0) {
  130.     *outSizePtr = 0;
  131.     FakePanicVoid("Swap_Buffer: incoming buffer not long-word aligned.\n");
  132.     }
  133. #endif NOTDEF
  134.  
  135.     /*
  136.      * '*' can only be the last character in a format string.
  137.      */
  138.     cPtr = strchr(format, '*');
  139.     if (cPtr != NULL && cPtr != &(format[strlen(format) - 1])) {
  140.     *outSizePtr = 0;
  141.     FakePanicVoid("Swap_Buffer: the format string can contain a '*' only in the last character.\n");
  142.     }
  143.  
  144.     formatPtr = format;
  145.     inPtr = inBuf;
  146.     outPtr = outBuf;
  147.     outSize = *outSizePtr;
  148.  
  149. #ifdef NOTDEF
  150.     if (((unsigned int) outBuf) % 4  != 0) {
  151.     *outSizePtr = 0;
  152.     FakePanicVoid("Swap_Buffer: outgoing buffer not long-word aligned.\n");
  153.     }
  154. #endif NOTDEF
  155.  
  156.     /*
  157.      * while there's still more in inbuf, and we haven't finished with
  158.      * the format string...
  159.      */
  160.     while (*formatPtr != '\0' && okayP) {
  161.     switch (*formatPtr) {
  162.     case 'b':
  163.         /* increments inPtr and outPtr and formatPtr */
  164.         okayP = CopyData(inType, &inPtr, inSize, inBuf, byteBuf, outType,
  165.             &outPtr, outSize, outBuf, &formatPtr, GetByte, PutByte);
  166.         break;
  167.     case 'h':
  168.         okayP = CopyData(inType, &inPtr, inSize, inBuf, halfWordBuf,
  169.             outType, &outPtr, outSize, outBuf, &formatPtr, GetHalfWord,
  170.             PutHalfWord);
  171.         break;
  172.     case 'w':
  173.         okayP = CopyData(inType, &inPtr, inSize, inBuf, wordBuf, outType,
  174.             &outPtr, outSize, outBuf, &formatPtr, GetWord, PutWord);
  175.         break;
  176.     case 'd':
  177.         okayP = CopyData(inType, &inPtr, inSize, inBuf, doubleBuf, outType,
  178.             &outPtr, outSize, outBuf, &formatPtr, GetDoubleWord,
  179.             PutDoubleWord);
  180.         break;
  181.     default:
  182.         *outSizePtr = 0;
  183.         FakePanicVoid(
  184.             "Swap_Buffer: unrecognized character in format string.\n");
  185.     }
  186.     }
  187.  
  188.     *outSizePtr = (unsigned int) outPtr - (unsigned int) outBuf;
  189.     /*
  190.      * Time for error checking now, in the following order.
  191.      * 1) Check to see if we ran off of outBuf, if so, return the necessary
  192.      *        size of outBuf in order to swap correctly.
  193.      * 2) Check to see if we're not at the end of the format string.  If we
  194.      *        are not, then we ran off the end of inBuf (or ourBuf, but
  195.      *        we checked that in #1) and we panic (saying inBuf too short).
  196.      * 3) Check to see if we didn't finish inBuf.  If so, then we ran off the
  197.      *        end of the format string (or outBuf, but we checked than in
  198.      *        #1) and we panic (saying format string not long enough).
  199.      * 4) There's no need to check to see if we didn't finish outBuf.
  200.      *        If we didn't, then either we ran off the end of inBuf
  201.      *        or we ran off the end of the format string, or both.
  202.      *        If we ran off the end of inBuf, but not format,
  203.      *        then we checked this in #2.  If we ran off the end
  204.      *        of format, but not inBuf, then we checked this in #3.
  205.      *        So we must have run off the end of both - and this is okay,
  206.      *        since it just means that they gave us an output buffer that
  207.      *        was too large, so return no error!  Just keep the actual
  208.      *        size of the output data in the *outSizePtr.
  209.      */
  210.  
  211.     /* #1 Did we run off the end of outBuf? */
  212.     if (*outSizePtr > outSize) {
  213.     /* return necessary size of output buffer */
  214.     (void) Swap_BufSize(inBuf, inSize, inType, outType, format, outSizePtr);
  215.     return;
  216.     }
  217.     /* #2 Did we not finish format? */
  218.     if (*formatPtr != '\0') {
  219.     *outSizePtr = 0;
  220.     FakePanicVoid("Swap_Buffer: ran out of input data before reaching the end of the format string.\n");
  221.     }
  222.     if (((unsigned int) inPtr - (unsigned int) inBuf) < inSize) {
  223.     *outSizePtr = 0;
  224.     FakePanicVoid("Swap_Buffer: format string was not long enough to account for the size of the input data.\n");
  225.     }
  226.  
  227.     return;
  228. }
  229.  
  230.  
  231. /*
  232.  *----------------------------------------------------------------------
  233.  *
  234.  * Swap_BufSize -- 
  235.  *
  236.  *    Calculate the necessary size of an output buffer to swap the incoming
  237.  *    data into.  This takes care of padding on the different machines
  238.  *    that would affect the size of the swapped data.
  239.  *
  240.  * Results:
  241.  *    None.
  242.  *
  243.  * Side effects:
  244.  *    *outSizePtr is set to the size necessary to hold the byte-swapped
  245.  *    input data.  This takes into account differences of padding on
  246.  *    the different machines.  If the output size can't be correctly
  247.  *    calculated, then *outSizePtr returns a 0.  This can happen if
  248.  *    something went wrong, such as the format string contained garbage or
  249.  *    contained a '*' that was not the last character, or the inBuf was
  250.  *    too short for the format string, or some such other error.  Note that
  251.  *    less error checking is done in this routine than in Swap_Buffer(), since
  252.  *    the size of the inBuf relative to the format string isn't checked
  253.  *    unless it's crucial to calculating *outSizePtr.  (This occurs if the
  254.  *    format string contains a '*'.)     If such an error occurs,
  255.  *    panic() in a user process or a Sys_Panic(SYS_WARNING, xxx) in the
  256.  *    kernel will describe the error.
  257.  *
  258.  *----------------------------------------------------------------------
  259.  */
  260. void
  261. Swap_BufSize(inBuf, inSize, inType, outType, format, outSizePtr)
  262.     char    *inBuf;        /* in-coming buffer with data to swap */
  263.     int        inSize;        /* in BYTES - size of in-coming data */
  264.     int        inType;        /* byte-order/padding of in-coming buffer */
  265.     int        outType;    /* byte-order/padding of out-going buffer */
  266.     char    *format;    /* format string of in-coming data */
  267.     int        *outSizePtr;    /* We calculate the necessary size of swapped
  268.                  * data, in BYTES and return that.
  269.                  */
  270. {
  271.     char    *inPtr;
  272.     int        okayP = 1;
  273.     char    *formatPtr;
  274.     char    *cPtr;
  275.  
  276.     /*
  277.      * '*' can only be the last character in a format string.
  278.      */
  279.     cPtr = strchr(format, '*');
  280.     if (cPtr != NULL && cPtr != &(format[strlen(format) - 1])) {
  281.     *outSizePtr = 0;
  282.     FakePanicVoid("Swap_BufSize: the format string can contain a '*' only in the last character.\n");
  283.     }
  284.  
  285.     inPtr = inBuf;
  286.     formatPtr = format;
  287.     *outSizePtr = 0;
  288.  
  289.     while (*formatPtr != '\0' && okayP) {
  290.     switch (*formatPtr) {
  291.     case 'b':
  292.         /*
  293.          * Increments inPtr, outSize and formatPtr
  294.          */
  295.         okayP = CalcSize(inType, &inPtr, inSize, inBuf, outType, outSizePtr,
  296.             &formatPtr, GetByte, CalcPutByteSize);
  297.         break;
  298.     case 'h':
  299.         okayP = CalcSize(inType, &inPtr, inSize, inBuf, outType, outSizePtr,
  300.             &formatPtr, GetHalfWord, CalcPutHalfWordSize);
  301.         break;
  302.     case 'w':
  303.         okayP = CalcSize(inType, &inPtr, inSize, inBuf, outType, outSizePtr,
  304.             &formatPtr, GetWord, CalcPutWordSize);
  305.         break;
  306.     case 'd':
  307.         okayP = CalcSize(inType, &inPtr, inSize, inBuf, outType, outSizePtr,
  308.             &formatPtr, GetDoubleWord, CalcPutDoubleSize);
  309.         break;
  310.     default:
  311.         /* I should say what character it is... */
  312.         *outSizePtr = 0;
  313.         FakePanicVoid("Swap_BufSize: unrecognized character in format string.\n");
  314.     }
  315.     }
  316.     if (!okayP) {
  317.     *outSizePtr = 0;
  318.     FakePanicVoid("Swap_BufSize: the size of the format string and inBuf were not compatible.\n");
  319.     }
  320.     return;
  321. }
  322.  
  323.  
  324. /*
  325.  *----------------------------------------------------------------------
  326.  *
  327.  * CalcSize -- 
  328.  *
  329.  *    Calculate needed size for output byte-swapped buffer.
  330.  *
  331.  * Results:
  332.  *    True (1) if everything went okay and we were able to calculate
  333.  *    the output buffer size.  False (0) if we weren't able to calculate
  334.  *    it.  This occurs when the format string contains a '*' and we run
  335.  *    out of the in-coming buffer space before we even get to the '*', or
  336.  *    when the format string contains garbage.
  337.  *
  338.  * Side effects:
  339.  *    *outSizePtr gets filled in with the needed size of the output buffer.
  340.  *
  341.  *----------------------------------------------------------------------
  342.  */
  343. static int
  344. CalcSize(inType, inPtrPtr, inSize, inBuf, outType, outSizePtr, formatPtrPtr,
  345.                                 GetFunc, SizeFunc)
  346.     int        inType;
  347.     char    **inPtrPtr;
  348.     int        inSize;
  349.     char    *inBuf;
  350.     int        outType;
  351.     int        *outSizePtr;
  352.     char    **formatPtrPtr;
  353.     int        (*GetFunc)();
  354.     void    (*SizeFunc)();
  355. {
  356.     int        repCount;
  357.     int        an_int;
  358.     char    *inPtr;
  359.     char    *formatPtr;
  360.     int        okayP = 1;
  361.     int        checkInSizeP = 0;
  362.     int        inSizeLeft;
  363.  
  364.     inPtr = *inPtrPtr;
  365.     formatPtr = *formatPtrPtr;
  366.  
  367.     /*
  368.      * We need to check the size remaining in the inBuf only if there's
  369.      * a '*' in the format string.   This is because we cannot calculate
  370.      * the outSize correctly if there's a '*' except by seeing how much
  371.      * data there really is in the inBuf.
  372.      */
  373.     if (strchr(formatPtr, '*') != NULL) {
  374.     checkInSizeP = 1;
  375.     }
  376.     formatPtr++;
  377.     repCount = 0;
  378.     while (*formatPtr != '\0' && isdigit(*formatPtr)) {
  379.     char    *testStr;
  380.     repCount *= 10;
  381.     an_int = strtol(formatPtr, &testStr, 10);
  382.     if (testStr == formatPtr) {
  383.         FakePanicValue("Bad format string.\n");
  384.     }
  385.     repCount += an_int;
  386.     formatPtr++;
  387.     }
  388.     /*
  389.      * If there were no digits following the type character, then set repCount
  390.      * to 1 so that we do 1 character.
  391.      */
  392.     if (repCount == 0) {
  393.     repCount = 1;
  394.     }
  395.     if (*formatPtr == '*') {
  396.     formatPtr++;
  397.     /*
  398.      * Infinity, since we count down until zero.
  399.      */
  400.     repCount = -1;
  401.     }
  402.  
  403.     while (repCount != 0 && (((unsigned int) inPtr) -
  404.         ((unsigned int) inBuf)) < inSize) {
  405.     /* increments inPtr */
  406.     if (checkInSizeP) {
  407.         inSizeLeft = inSize - ((unsigned int) inPtr - (unsigned int) inBuf);
  408.         okayP = (*GetFunc)(inType, &inPtr, NULL, inSizeLeft);
  409.         if (!okayP) {
  410.         return 0;
  411.         }
  412.     }
  413.     /* increments outSize */
  414.     (*SizeFunc)(outType, outSizePtr);
  415.     repCount--;
  416.     }
  417.     *inPtrPtr = inPtr;
  418.     *formatPtrPtr = formatPtr;
  419.     return 1;
  420. }
  421.  
  422.  
  423. /*
  424.  *----------------------------------------------------------------------
  425.  *
  426.  * CopyData -- 
  427.  *
  428.  *    Byte-swap and copy a piece of data.
  429.  *
  430.  * Results:
  431.  *    None.
  432.  *
  433.  * Side effects:
  434.  *    The data is copied from the inBuf to the outBuf using given
  435.  *    retrieval and copy functions.
  436.  *
  437.  *----------------------------------------------------------------------
  438.  */
  439. static int
  440. CopyData(inType, inPtrPtr, inSize, inBuf, buf, outType, outPtrPtr,
  441.                         outSize, outBuf, formatPtrPtr,
  442.                         GetFunc, PutFunc)
  443.     int        inType;
  444.     char    **inPtrPtr;
  445.     int        inSize;
  446.     char    *inBuf;
  447.     char    *buf;
  448.     int        outType;
  449.     char    **outPtrPtr;
  450.     int        outSize;
  451.     char    *outBuf;
  452.     char    **formatPtrPtr;
  453.     int        (*GetFunc)();
  454.     int        (*PutFunc)();
  455. {
  456.     char    *inPtr;
  457.     char    *outPtr;
  458.     char    *formatPtr;
  459.     int        an_int;
  460.     int        repCount;
  461.     int        inSizeLeft;
  462.     int        outSizeLeft;
  463.     int        okayP = 1;
  464.  
  465.     inPtr = *inPtrPtr;
  466.     outPtr = *outPtrPtr;
  467.     formatPtr = *formatPtrPtr;
  468.  
  469.     formatPtr++;
  470.     repCount = 0;
  471.     while (*formatPtr != '\0' && isdigit(*formatPtr)) {
  472.     char    *testStr;
  473.     repCount *= 10;
  474.     an_int = strtol(formatPtr, &testStr, 10);
  475.     if (testStr == formatPtr) {
  476.         FakePanicValue("Ioctl format string bad.\n");
  477.     }
  478.     repCount += an_int;
  479.     formatPtr++;
  480.     }
  481.     /*
  482.      * If there were no digits following the type character, then set repCount
  483.      * to 1 so that we do 1 character.
  484.      */
  485.     if (repCount == 0) {
  486.     repCount = 1;
  487.     }
  488.     if (*formatPtr != '\0' && *formatPtr == '*') {
  489.     formatPtr++;
  490.     /*
  491.      * Infinity, since we count down until zero.
  492.      */
  493.     repCount = -1;
  494.     }
  495.     while (repCount != 0 && okayP) {
  496.     inSizeLeft = inSize - ((unsigned int) inPtr - (unsigned int) inBuf);
  497.     outSizeLeft = outSize - ((unsigned int) outPtr - (unsigned int) outBuf);
  498.     /* increments inPtr */
  499.     okayP = (*GetFunc)(inType, &inPtr, buf, inSizeLeft);
  500.     /* increments outPtr */
  501.     if (okayP) {
  502.         okayP = (*PutFunc)(outType, &outPtr, buf, outSizeLeft);
  503.     }
  504.     repCount--;
  505.     }
  506.  
  507.     *inPtrPtr = inPtr;
  508.     *outPtrPtr = outPtr;
  509.     *formatPtrPtr = formatPtr;
  510.  
  511.     return okayP;
  512. }
  513.  
  514.  
  515. /*
  516.  *----------------------------------------------------------------------
  517.  *
  518.  * GetByte, GetHalfWord, GetWord, GetDoubleWord -- 
  519.  *
  520.  *    Using the given byte-alignment type, grab the next bytes in the buffer.
  521.  *    If the buf param isn't NULL, the grabbed bytes will be put into it.
  522.  *
  523.  *    In the case of halfwords, words, and doubles, some byte-swapping may
  524.  *    be necessary.  If the inType of the buffer is of a different
  525.  *    alignment, some skipping of byte padding may be necessary before
  526.  *    grabbing the desired bytes.
  527.  *
  528.  *    Regardless, buf will be filled with bytes in the following order,
  529.  *    with no padding:
  530.  *        byte:    buf[0] is the byte.
  531.  *        halfword:    buf[0] is low byte, buf[1] is high byte.
  532.  *        word:    buf[0] is low byte, ..., buf[3] is high byte.
  533.  *        double:    buf[0] is low byte, ..., buf[7] is high byte.
  534.  *
  535.  * Results:
  536.  *    True (1) if everyting goes okay, and false (0) if there isn't enough
  537.  *    space left in inBuf.
  538.  *
  539.  * Side effects:
  540.  *    The byte grabbed is put into buf, if it isn't NULL.  The ptr into
  541.  *    the input buffer is incremented.  Even if there wasn't enough buffer
  542.  *    space, the routine increments the ptrs to where they would be if there
  543.  *    had been, so the calling routine can see what should have happened.
  544.  *
  545.  *----------------------------------------------------------------------
  546.  */
  547. /*ARGSUSED*/
  548. static int
  549. GetByte(inType, inPtrPtr, buf, inSizeLeft)
  550.     int        inType;
  551.     char    **inPtrPtr;
  552.     char    *buf;
  553.     int        inSizeLeft;
  554. {
  555.     if (buf != NULL && inSizeLeft >= 1) {
  556.     buf[0] = **inPtrPtr;
  557.     }
  558.     (*inPtrPtr)++;
  559.  
  560.     return (inSizeLeft >= 1);
  561. }
  562.  
  563. static int
  564. GetHalfWord(inType, inPtrPtr, buf, inSizeLeft)
  565.     int        inType;
  566.     char    **inPtrPtr;
  567.     char    *buf;
  568.     int        inSizeLeft;
  569. {
  570.     if (inType == SWAP_SUN_TYPE || inType == SWAP_SPARC_TYPE) {
  571.     /* one-byte padding if necessary */
  572.     if ((((unsigned int) *inPtrPtr) % 2) != 0) {
  573.         if (buf != NULL && inSizeLeft >= 3) {
  574.         buf[0] = *((*inPtrPtr) + 1);
  575.         buf[1] = *((*inPtrPtr) + 2);
  576.         }
  577.         *inPtrPtr += 3;
  578.         return (inSizeLeft >= 3);
  579.     } else {
  580.         if (buf != NULL && inSizeLeft >= 2) {
  581.         buf[0] = **inPtrPtr;
  582.         buf[1] = *((*inPtrPtr) + 1);
  583.         }
  584.         *inPtrPtr += 2;
  585.         return (inSizeLeft >= 2);
  586.     }
  587.     } else if (inType == SWAP_VAX_TYPE || inType == SWAP_SPUR_TYPE) {
  588.     /* one-byte padding if necessary */
  589.     if ((((unsigned int) *inPtrPtr) % 2) != 0) {
  590.         if (buf != NULL && inSizeLeft >= 3) {
  591.         buf[0] = *((*inPtrPtr) + 2);
  592.         buf[1] = *((*inPtrPtr) + 1);
  593.         }
  594.         *inPtrPtr += 3;
  595.         return (inSizeLeft >= 3);
  596.     } else {
  597.         if (buf != NULL && inSizeLeft >= 2) {
  598.         buf[0] = *((*inPtrPtr) + 1);
  599.         buf[1] = **inPtrPtr;
  600.         }
  601.         *inPtrPtr += 2;
  602.         return (inSizeLeft >= 2);
  603.     }
  604.     }
  605.     /* for lint */
  606.     return 0;
  607. }
  608.  
  609. static int
  610. GetWord(inType, inPtrPtr, buf, inSizeLeft)
  611.     int        inType;
  612.     char    **inPtrPtr;
  613.     char    *buf;
  614.     int        inSizeLeft;
  615. {
  616.     int        fix_it;
  617.  
  618.     if (inType == SWAP_SUN_TYPE) {
  619.     /* one-byte padding if necessary */
  620.     fix_it = (2 - (((unsigned int) *inPtrPtr) % 2)) % 2;
  621.     if (buf != NULL && inSizeLeft >= 4 + fix_it) {
  622.         buf[0] = *((*inPtrPtr) + fix_it);
  623.         buf[1] = *((*inPtrPtr) + fix_it + 1);
  624.         buf[2] = *((*inPtrPtr) + fix_it + 2);
  625.         buf[3] = *((*inPtrPtr) + fix_it + 3);
  626.     }
  627.     (*inPtrPtr) += 4 + fix_it;
  628.     return (inSizeLeft >= 4 + fix_it);
  629.     } else if (inType == SWAP_VAX_TYPE) {
  630.     fix_it = (2 - (((unsigned int) *inPtrPtr) % 2)) % 2;
  631.     if (buf != NULL && inSizeLeft >= 4 + fix_it) {
  632.         buf[0] = *((*inPtrPtr) + fix_it + 3);
  633.         buf[1] = *((*inPtrPtr) + fix_it + 2);
  634.         buf[2] = *((*inPtrPtr) + fix_it + 1);
  635.         buf[3] = *((*inPtrPtr) + fix_it);
  636.     }
  637.     (*inPtrPtr) += 4 + fix_it;
  638.     return (inSizeLeft >= 4 + fix_it);
  639.     } else if (inType == SWAP_SPUR_TYPE) {
  640.     fix_it = (4 - (((unsigned int) *inPtrPtr) % 4)) % 4;
  641.     if (buf != NULL && inSizeLeft >= 4 + fix_it) {
  642.         buf[0] = *(*inPtrPtr + fix_it + 3);
  643.         buf[1] = *(*inPtrPtr + fix_it + 2);
  644.         buf[2] = *(*inPtrPtr + fix_it + 1);
  645.         buf[3] = *(*inPtrPtr + fix_it);
  646.     }
  647.     (*inPtrPtr) += 4 + fix_it;
  648.     return (inSizeLeft >= 4 + fix_it);
  649.     } else if (inType == SWAP_SPARC_TYPE) {
  650.     fix_it = (4 - (((unsigned int) *inPtrPtr) % 4)) % 4;
  651.     if (buf != NULL && inSizeLeft >= 4 + fix_it) {
  652.         buf[0] = *(*inPtrPtr + fix_it);
  653.         buf[1] = *(*inPtrPtr + fix_it + 1);
  654.         buf[2] = *(*inPtrPtr + fix_it + 2);
  655.         buf[3] = *(*inPtrPtr + fix_it + 3);
  656.     }
  657.     (*inPtrPtr) += 4 + fix_it;
  658.     return (inSizeLeft >= 4 + fix_it);
  659.  
  660.     }
  661.     /* for lint */
  662.     return 0;
  663. }
  664.  
  665. /*ARGSUSED*/
  666. static int
  667. GetDoubleWord(inType, inPtrPtr, buf, inSizeLeft)
  668.     int        inType;
  669.     char    **inPtrPtr;
  670.     char    *buf;
  671.     int        inSizeLeft;
  672. {
  673.     /* what does this mean and where? */
  674.     FakePanicValue("GetDoubleWord:  don't know what a double means yet.\n");
  675. }
  676.  
  677.  
  678. /*
  679.  *----------------------------------------------------------------------
  680.  *
  681.  * CalcPutByteSize, CalcPutHalfWordSize, CalcPutWordSize, CalcPutDoubleSize -- 
  682.  *
  683.  *    Using the given byte-alignment type, figure out how much space is
  684.  *    required in the output buffer to add the next bytes.  This means
  685.  *    figuring out if padding is required on the machine type of the output
  686.  *    buffer.
  687.  *
  688.  *    We assume that outSizePtr is the current offset from the beginning
  689.  *    of a long-word aligned buffer.
  690.  *
  691.  * Results:
  692.  *    None.
  693.  *
  694.  * Side effects:
  695.  *    outSize is incremented to record the amount of space required.
  696.  *
  697.  *----------------------------------------------------------------------
  698.  */
  699. /*ARGSUSED*/
  700. static void
  701. CalcPutByteSize(outType, outSizePtr)
  702.     int        outType;
  703.     int        *outSizePtr;
  704. {
  705.     (*outSizePtr)++;
  706.     return;
  707. }
  708.  
  709. static void
  710. CalcPutHalfWordSize(outType, outSizePtr)
  711.     int        outType;
  712.     int        *outSizePtr;
  713. {
  714.     if (outType == SWAP_SUN_TYPE || outType == SWAP_VAX_TYPE ||
  715.         outType == SWAP_SPUR_TYPE || outType == SWAP_SPARC_TYPE) {
  716.     if ((((unsigned int) *outSizePtr) % 2) != 0) {
  717.         /* one byte padding to short-word align the thing */
  718.         (*outSizePtr) += 3;
  719.     } else {
  720.         (*outSizePtr) += 2;
  721.     }
  722.     }
  723.     return;
  724. }
  725.  
  726. static void
  727. CalcPutWordSize(outType, outSizePtr)
  728.     int        outType;
  729.     int        *outSizePtr;
  730. {
  731.     int        fix_it;
  732.  
  733.     if (outType == SWAP_SUN_TYPE || outType == SWAP_VAX_TYPE) {
  734.     if ((((unsigned int) *outSizePtr) % 2) != 0) {
  735.         /* one byte padding to short-word align the thing */
  736.         (*outSizePtr) += 5;
  737.     } else {
  738.         (*outSizePtr) += 4;
  739.     }
  740.     } else if (outType == SWAP_SPUR_TYPE || outType == SWAP_SPARC_TYPE) {
  741.     fix_it = (4 - (((unsigned int) *outSizePtr) % 4)) % 4;
  742.     /* byte padding to long-word align the thing */
  743.     (*outSizePtr) += 4 + fix_it;
  744.     }
  745.     return;
  746. }
  747.  
  748. /*ARGSUSED*/
  749. static void
  750. CalcPutDoubleSize(outType, outSizePtr)
  751.     int        outType;
  752.     int        *outSizePtr;
  753. {
  754.     FakePanicVoid("CalcPutDoubleSize: Don't know what this means yet.\n");
  755. }
  756.  
  757.  
  758. /*
  759.  *----------------------------------------------------------------------
  760.  *
  761.  * PutByte, PutHalfWord, PutWord, PutDoubleWord -- 
  762.  *
  763.  *    Using the given byte-alignment type, byte-swap and pad the data in
  764.  *    the buffer as necessary and copy it to the outBuf.
  765.  *
  766.  *    We assume that outSizePtr is the current offset from the beginning
  767.  *    of a long-word aligned buffer.
  768.  *
  769.  *    The data in buf is ordered with buf[0] as low byte and buf[n] as
  770.  *    high byte, with no padding.  So if the outType machine type requires
  771.  *    byte-swapping or padding from the current outPtr location, this is
  772.  *    done here.
  773.  *
  774.  * Results:
  775.  *    True (1) if everything goes okay, false (0) if there isn't enough
  776.  *    space left in outBuf.
  777.  *
  778.  * Side effects:
  779.  *    outSize is incremented to record the amount of space required.
  780.  *    outPtr is incremented to its new position.
  781.  *    Data is copied into outPtr's buffer.  Even if there wasn't enough buffer
  782.  *    space, the routine increments the ptrs to where they would be if there
  783.  *    had been, so the calling routine can see what should have happened.
  784.  *
  785.  *----------------------------------------------------------------------
  786.  */
  787. /*ARGSUSED*/
  788. static int
  789. PutByte(outType, outPtrPtr, buf, outSizeLeft)
  790.     int        outType;
  791.     char    **outPtrPtr;
  792.     char    *buf;
  793.     int        outSizeLeft;
  794. {
  795.     if (outSizeLeft >= 1) {
  796.     **outPtrPtr = buf[0];
  797.     }
  798.     (*outPtrPtr)++;
  799.     return (outSizeLeft >= 1);
  800.  
  801. }
  802.  
  803. static int
  804. PutHalfWord(outType, outPtrPtr, buf, outSizeLeft)
  805.     int        outType;
  806.     char    **outPtrPtr;
  807.     char    *buf;
  808.     int        outSizeLeft;
  809. {
  810.     if (outType == SWAP_SUN_TYPE || outType == SWAP_SPARC_TYPE) {
  811.     if ((((unsigned int) *outPtrPtr) % 2) != 0) {
  812.         if (outSizeLeft >= 3) {
  813.         **outPtrPtr = 0;
  814.         *(*outPtrPtr + 1) = buf[0];
  815.         *(*outPtrPtr + 2) = buf[1];
  816.         }
  817.         (*outPtrPtr) += 3;
  818.         return (outSizeLeft >= 3);
  819.     } else {
  820.         if (outSizeLeft >= 2) {
  821.         **outPtrPtr = buf[0];
  822.         *(*outPtrPtr + 1) = buf[1];
  823.         }
  824.         (*outPtrPtr) += 2;
  825.         return (outSizeLeft >= 2);
  826.     }
  827.     } else if (outType == SWAP_VAX_TYPE || outType == SWAP_SPUR_TYPE) {
  828.     if ((((unsigned int) *outPtrPtr) % 2) != 0) {
  829.         if (outSizeLeft >= 3) {
  830.         **outPtrPtr = 0;
  831.         *(*outPtrPtr + 1) = buf[1];
  832.         *(*outPtrPtr + 2) = buf[0];
  833.         }
  834.         (*outPtrPtr) += 3;
  835.         return (outSizeLeft >= 3);
  836.     } else {
  837.         if (outSizeLeft >= 2) {
  838.         **outPtrPtr = buf[1];
  839.         *(*outPtrPtr + 1) = buf[0];
  840.         }
  841.         (*outPtrPtr) += 2;
  842.         return (outSizeLeft >= 2);
  843.     }
  844.     }
  845.     /* for lint */
  846.     return 0;
  847. }
  848.  
  849. static int
  850. PutWord(outType, outPtrPtr, buf, outSizeLeft)
  851.     int        outType;
  852.     char    **outPtrPtr;
  853.     char    *buf;
  854.     int        outSizeLeft;
  855. {
  856.     int        fix_it;
  857.     int        i;
  858.  
  859.     if (outType == SWAP_SUN_TYPE) {
  860.     /* fix_it = 0 or 1 */
  861.     fix_it = (2 - (((unsigned int) *outPtrPtr) % 2)) % 2;
  862.     if (outSizeLeft >= 4 + fix_it) {
  863.         **outPtrPtr = 0;    /* Takes care of padding if fix_it = 1 */
  864.         *(*outPtrPtr + fix_it) = buf[0];
  865.         *(*outPtrPtr + fix_it + 1) = buf[1];
  866.         *(*outPtrPtr + fix_it + 2) = buf[2];
  867.         *(*outPtrPtr + fix_it + 3) = buf[3];
  868.     }
  869.     (*outPtrPtr) += 4 + fix_it;
  870.     return (outSizeLeft >= 4 + fix_it);
  871.     } else if (outType == SWAP_VAX_TYPE) {
  872.     /* fix_it = 0 or 1 */
  873.     fix_it = (2 - (((unsigned int) *outPtrPtr) % 2)) % 2;
  874.     if (outSizeLeft >= 4 + fix_it) {
  875.         **outPtrPtr = 0;    /* Takes care of padding if fix_it = 1 */
  876.         *(*outPtrPtr + fix_it) = buf[3];
  877.         *(*outPtrPtr + fix_it + 1) = buf[2];
  878.         *(*outPtrPtr + fix_it + 2) = buf[1];
  879.         *(*outPtrPtr + fix_it + 3) = buf[0];
  880.     }
  881.     (*outPtrPtr) += 4 + fix_it;
  882.     return (outSizeLeft >= 4 + fix_it);
  883.     } else if (outType == SWAP_SPUR_TYPE) {
  884.     fix_it = (4 - (((unsigned int) *outPtrPtr) % 4)) % 4;
  885.     /* padding */
  886.     if (outSizeLeft >= 4 + fix_it) {
  887.         for (i = 0; i < fix_it; i++) {
  888.         *(*outPtrPtr + i) = 0;
  889.         }
  890.         *(*outPtrPtr + fix_it) = buf[3];
  891.         *(*outPtrPtr + fix_it + 1) = buf[2];
  892.         *(*outPtrPtr + fix_it + 2) = buf[1];
  893.         *(*outPtrPtr + fix_it + 3) = buf[0];
  894.     }
  895.     (*outPtrPtr) += 4 + fix_it;
  896.     return (outSizeLeft >= 4 + fix_it);
  897.     } else if (outType == SWAP_SPARC_TYPE) {
  898.     fix_it = (4 - (((unsigned int) *outPtrPtr) % 4)) % 4;
  899.     /* padding */
  900.     if (outSizeLeft >= 4 + fix_it) {
  901.         for (i = 0; i < fix_it; i++) {
  902.         *(*outPtrPtr + i) = 0;
  903.         }
  904.         *(*outPtrPtr + fix_it) = buf[0];
  905.         *(*outPtrPtr + fix_it + 1) = buf[1];
  906.         *(*outPtrPtr + fix_it + 2) = buf[2];
  907.         *(*outPtrPtr + fix_it + 3) = buf[3];
  908.     }
  909.     (*outPtrPtr) += 4 + fix_it;
  910.     return (outSizeLeft >= 4 + fix_it);
  911.     }
  912.     /* for lint */
  913.     return 0;
  914. }
  915.  
  916. /*ARGSUSED*/
  917. static int
  918. PutDoubleWord(outType, outPtrPtr, buf, outSizeLeft)
  919.     int        outType;
  920.     char    **outPtrPtr;
  921.     char    *buf;
  922.     int        outSizeLeft;
  923. {
  924.     FakePanicValue("PutDoubleWord: Don't know what this means yet.\n");
  925. }
  926.